﻿using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;

namespace MaiYao
{
    class 窗口_
    {
        // 导入 Windows API 函数
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        [DllImport("user32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        public const int SWP_NOSIZE = 0x0001;
        public const int SWP_NOMOVE = 0x0002;
        public const int SWP_NOZORDER = 0x0004;
        public const uint SWP_SHOWWINDOW = 0x0040;
        public const int GWL_STYLE = -16;
        public const long WS_MINIMIZE = 0x2000000L;

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern int GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
        [DllImport("user32.dll")]
        public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        public static extern IntPtr WindowFromPoint(POINT p);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetCursorPos(out POINT lpPoint);

        // 导入GetWindowRect API
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

        // 导入GetClientRect API
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);

        // 导入ClientToScreen API，用于转换客户区坐标到屏幕坐标
        [DllImport("user32.dll")]
        public static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);

        // 定义RECT结构体
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;        // 矩形左边界的x坐标
            public int Top;         // 矩形上边界的y坐标
            public int Right;       // 矩形右边界的x坐标
            public int Bottom;      // 矩形下边界的y坐标
            public override string ToString()
            {
                return Left.ToString() + ", " + Top.ToString() + ", " + Right.ToString() + ", " + Bottom.ToString();
            }
        }

        // 定义POINT结构体，用于ClientToScreen函数
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;
            public POINT(int x, int y)
            {
                X = x;
                Y = y;
            }
            public override string ToString()
            {
                return X.ToString() + ", " + Y.ToString();
            }
        }

        [Flags]
        public enum ShowWindowCommands : int
        {
            SW_HIDE = 0,
            SW_SHOWNORMAL = 1,
            SW_NORMAL = 1,
            SW_SHOWMINIMIZED = 2,
            SW_SHOWMAXIMIZED = 3,
            SW_MAXIMIZE = 3,
            SW_SHOWNOACTIVATE = 4,
            SW_SHOW = 5,
            SW_MINIMIZE = 6,
            SW_SHOWMINNOACTIVE = 7,
            SW_SHOWNA = 8,
            SW_RESTORE = 9,
            SW_SHOWDEFAULT = 10,
            SW_FORCEMINIMIZE = 11,
            SW_MAX = 11
        }

        [DllImport("user32.dll")]
        public static extern ShowWindowCommands ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CloseWindow(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase);

        // 导入 Windows API 函数
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        public static void 设为前台窗口(IntPtr hWnd)
        {
            SetForegroundWindow(hWnd);
        }

        public static string 获取窗口类名(IntPtr hwnd)
        {
            if (hwnd == IntPtr.Zero)
            {
                return string.Empty;
            }

            const int maxLength = 256;
            var classNameBuilder = new System.Text.StringBuilder(maxLength);

            int result = GetClassName(hwnd, classNameBuilder, maxLength);
            if (result == 0)
            {
                // 获取失败，获取错误码
                int errorCode = Marshal.GetLastWin32Error();
                Console.WriteLine($"获取窗口类名失败，错误码: {errorCode}");
                return string.Empty;
            }

            return classNameBuilder.ToString();
        }

        public static Rectangle 获取客户端矩形(IntPtr hWnd)
        {
            GetClientRect(hWnd, out var rect);
            return Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom);
        }

        public static System.Drawing.Point 客户端坐标转为屏幕坐标(IntPtr hWnd, System.Drawing.Point p)
        {
            var P = new POINT(p.X, p.Y);
            ClientToScreen(hWnd, ref P);
            return new System.Drawing.Point(P.X, P.Y);
        }

        public static bool 刷新窗口(IntPtr hWnd)
        {
            return InvalidateRect(hWnd, IntPtr.Zero, true);
        }
        public static bool 窗口是最小化的(IntPtr hWnd)
        {
            long style = 窗口_.GetWindowLong(hWnd, 窗口_.GWL_STYLE);
            return (style & 窗口_.WS_MINIMIZE) == 窗口_.WS_MINIMIZE;
        }

        public static void 最小化窗口(IntPtr hWnd)
        {
            窗口_.ShowWindow(hWnd, 窗口_.ShowWindowCommands.SW_MINIMIZE);
        }

        public static void 置顶窗口(IntPtr hWnd)
        {
            窗口_.SetWindowPos(hWnd, -1, 0, 0, 0, 0, 窗口_.SWP_NOSIZE);
        }

        public static void 取消置顶窗口(IntPtr hWnd)
        {
            窗口_.SetWindowPos(hWnd, -2, 0, 0, 0, 0, 窗口_.SWP_NOSIZE);
        }

        public static void 恢复窗口(IntPtr hWnd)
        {
            窗口_.ShowWindow(hWnd, 窗口_.ShowWindowCommands.SW_RESTORE);
        }

        public static bool 关闭窗口(IntPtr hWnd)
        {
            return 窗口_.CloseWindow(hWnd);
        }


        [DllImport("user32.dll")]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        public static extern bool SetWindowText(IntPtr hWnd, string lpString);

        public static void MoveToBottomRight(IntPtr hWnd, int width, int height)
        {
            int x = (int)(SystemParameters.PrimaryScreenWidth - width);
            int y = (int)(SystemParameters.PrimaryScreenHeight - height);

            SetWindowPos(hWnd, 0, x, y, width, height, 0);
        }

        [DllImport("user32.dll")]
        private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

        // 枚举窗口的委托
        private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);


        public static Thickness GetTaskbarThickness()
        {
            IntPtr taskbarHandle = FindWindow("Shell_TrayWnd", null);
            if (taskbarHandle == IntPtr.Zero)
            {
                return new Thickness();
            }

            GetWindowRect(taskbarHandle, out RECT taskbarRect);
            System.Windows.Forms.Screen primaryScreen = System.Windows.Forms.Screen.PrimaryScreen;

            double width = taskbarRect.Right - taskbarRect.Left;
            double height = taskbarRect.Bottom - taskbarRect.Top;

            if (taskbarRect.Left == 0 && taskbarRect.Top == 0 &&
                width == primaryScreen.Bounds.Width && height < primaryScreen.Bounds.Height)
            {
                // 顶部任务栏
                return new Thickness(0, height, 0, 0);
            }
            else if (taskbarRect.Left == 0 &&
                     width == primaryScreen.Bounds.Width &&
                     taskbarRect.Top == primaryScreen.Bounds.Height - height)
            {
                // 底部任务栏
                return new Thickness(0, 0, 0, height);
            }
            else if (taskbarRect.Top == 0 &&
                     height == primaryScreen.Bounds.Height &&
                     width < primaryScreen.Bounds.Width)
            {
                // 左侧任务栏
                return new Thickness(width, 0, 0, 0);
            }
            else
            {
                // 右侧任务栏
                return new Thickness(0, 0, width, 0);
            }
        }

        public enum 窗口位置_
        {
            L,
            T,
            R,
            B
        }

        public static double GetTaskbarPosition(窗口位置_ 位置)
        {
            IntPtr taskbarHandle = FindWindow("Shell_TrayWnd", null);
            if (taskbarHandle == IntPtr.Zero)
            {
                return 0;
            }

            GetWindowRect(taskbarHandle, out RECT taskbarRect);
            if (位置 == 窗口位置_.T)
            {
                return taskbarRect.Top;
            }
            if (位置 == 窗口位置_.L)
            {
                return taskbarRect.Left;
            }
            if (位置 == 窗口位置_.R)
            {
                return taskbarRect.Right;
            }
            return taskbarRect.Bottom;
        }

        public static IntPtr DetectProcess(string processName)
        {
            Process[] processes = Process.GetProcessesByName(processName);

            if (processes.Length == 0)
            {
                return IntPtr.Zero;
            }
            return processes[0].Handle;
        }
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

    }
}
